package com.jige.jigetodo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jige.jigetodo.common.BaseResponse;
import com.jige.jigetodo.common.ErrorCode;
import com.jige.jigetodo.constant.CommonConstant;
import com.jige.jigetodo.constant.UserConstant;
import com.jige.jigetodo.controller.CaptchaController;
import com.jige.jigetodo.exception.BusinessException;
import com.jige.jigetodo.exception.ThrowUtils;
import com.jige.jigetodo.mapper.UserMapper;
import com.jige.jigetodo.model.dto.user.UserQueryRequest;
import com.jige.jigetodo.model.dto.user.UserUpdateRequest;
import com.jige.jigetodo.model.entity.User;
import com.jige.jigetodo.model.vo.UserVO;
import com.jige.jigetodo.service.UserService;
import com.jige.jigetodo.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.jige.jigetodo.constant.UserConstant.USER_LOGIN_STATE;

/**
 * @author Administrator
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2025-05-06 17:07:27
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    /**
     * 用户注册
     *
     * @return
     */
    @Override
    public boolean register(String account, String password, String checkPassword,String code,HttpServletRequest request) throws IOException {
        ThrowUtils.throwIf(account.length() < 3, ErrorCode.PARAMS_ERROR, "账号长度不能小于4位");
        ThrowUtils.throwIf(password.length() < 7 || checkPassword.length() <= 7, ErrorCode.PARAMS_ERROR, "密码不能小于8位");
        ThrowUtils.throwIf(!password.equals(checkPassword), ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
        //  加锁
        HttpSession session = request.getSession();
        String captcha = (String) session.getAttribute("captcha");
        ThrowUtils.throwIf(!code.equalsIgnoreCase(captcha),ErrorCode.PARAMS_ERROR,"验证码错误");
        synchronized (account.intern()) {
            //  账号不能重复
            QueryWrapper<User> querywrapper = new QueryWrapper<>();
            querywrapper.eq("userAccount", account);
            Long count = this.baseMapper.selectCount(querywrapper);
            if (count > 0) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "账号已存在");
            }
            //加盐
            String saltPassword = passwordSalt(password);
            User user = new User();
            user.setUserAccount(account);
            user.setUserPassword(saltPassword);
            //  操作数据库
            boolean result = save(user);
            ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "注册失败，数据库错误");
            return true;
        }
    }

    /**
     * 用户登录
     *
     * @param account
     * @param password
     * @param request
     * @return
     */
    @Override
    public UserVO userLogin(String account, String password,String code, HttpServletRequest request) {
        //  查询用户是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        QueryWrapper<User> userAccount = queryWrapper.eq("userAccount", account);
        User user = this.getOne(userAccount);
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户名或者密码错误");
        //  密码加密后与数据库的密码比对
        String saltPassword = passwordSalt(password);
        ThrowUtils.throwIf(!user.getUserPassword().equals(saltPassword), ErrorCode.PARAMS_ERROR, "用户名或者密码错误");
        //  校验验证码
        HttpSession session = request.getSession();
        String captcha = (String) session.getAttribute("captcha");
        ThrowUtils.throwIf(!code.equalsIgnoreCase(captcha),ErrorCode.PARAMS_ERROR,"验证码错误");
        //  如果成功，则保存用户的登录态到Session中
        request.getSession().setAttribute(USER_LOGIN_STATE, user);
        UserVO userVO = new UserVO();
        return userVO.objToVO(user);
    }

    @Override
    public boolean userLogOut(HttpServletRequest request) {
        //  判断用户是否已经登录
        Object attribute = request.getSession().getAttribute(USER_LOGIN_STATE);
        ThrowUtils.throwIf(attribute == null, ErrorCode.NOT_LOGIN_ERROR);
        //  移除用户的登录态
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return true;
    }

    /**
     * 更新用户信息
     *
     * @param userUpdateRequest
     * @return
     */
    @Override
    public boolean updateUser(UserUpdateRequest userUpdateRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(userUpdateRequest == null, ErrorCode.PARAMS_ERROR);
        //  判断用户是否已经登录
        ThrowUtils.throwIf(request.getSession().getAttribute(USER_LOGIN_STATE) == null, ErrorCode.NOT_LOGIN_ERROR);
        String userAvatar = userUpdateRequest.getUserAvatar();
        String userProfile = userUpdateRequest.getUserProfile();
        String userName = userUpdateRequest.getUserName();
        Long id = userUpdateRequest.getUserId();
        //查询用户是否存在
        User user = this.getById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
        //操作数据库
        if (StrUtil.isNotBlank(userAvatar)) {
            user.setUserAvatar(userAvatar);
        }
        if (StrUtil.isNotBlank(userProfile)) {
            user.setUserProfile(userProfile);
        }
        if (StrUtil.isNotBlank(userName)){
            user.setUserName(userName);
        }
        this.baseMapper.updateById(user);
        return true;
    }

    /**
     * 重置密码
     *
     * @param username
     * @param oldPassword
     * @param newPassword
     * @param checkPassword
     * @return
     */
    @Override
    public boolean resetPassword(String userAccount, String oldPassword, String newPassword, String checkPassword) {
        // 查询是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StrUtil.isNotBlank(userAccount),"userAccount",userAccount);
        User user = this.getOne(queryWrapper);
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR);
        ThrowUtils.throwIf(StrUtil.isBlank(oldPassword), ErrorCode.PARAMS_ERROR, "请输入原密码");
        String oldPassword1 = passwordSalt(oldPassword);
        ThrowUtils.throwIf(!oldPassword1.equals(user.getUserPassword()), ErrorCode.OPERATION_ERROR, "与原密码不一致");
        // 校验数据
        if (StrUtil.isBlank(newPassword) || StrUtil.isBlank(checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请输入密码或确认密码");
        }
        ThrowUtils.throwIf(newPassword.length() < 7, ErrorCode.PARAMS_ERROR, "新密码不能小于8位");
        ThrowUtils.throwIf(!newPassword.equals(checkPassword), ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
        user.setUserPassword(passwordSalt(newPassword));
        //  操作数据库，更新密码
        this.updateById(user);
        return true;
    }

    /**
     * 根据ID查询用户
     *
     * @param id
     * @return
     */
    @Override
    public User getUserById(Long id, HttpServletRequest request) {
        //  用户是否登录
        ThrowUtils.throwIf(request.getSession().getAttribute(USER_LOGIN_STATE) == null, ErrorCode.NOT_LOGIN_ERROR);
        User user = this.getById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
        return this.getById(id);
    }

    /**
     * 根据id查询用户脱敏信息
     *
     * @param id
     * @return
     */
    @Override
    public UserVO getUserVOById(Long id, HttpServletRequest request) {
        //  判断是否登录
        ThrowUtils.throwIf(request.getSession().getAttribute(USER_LOGIN_STATE) == null, ErrorCode.NOT_LOGIN_ERROR);
        User user = this.getById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
        UserVO userVO = new UserVO();
        return userVO.objToVO(user);
    }

    /*@Override
    public List<User> listUserByPage(List<User> userList,HttpServletRequest request) {
        if (CollUtil.isEmpty(userList)) {
            return new ArrayList<>();
        }
        return userList.stream()
                .map(user -> getUserById(user.getId(),request))
                .collect(Collectors.toList());
    }*/

    @Override
    public List<UserVO> listUserVOByPage(List<User> userList, HttpServletRequest request) {
        if (CollUtil.isEmpty(userList)) {
            return new ArrayList<>();
        }
        return userList.stream()
                .map(user -> getUserVOById(user.getId(), request))
                .collect(Collectors.toList());
    }

    @Override
    public QueryWrapper<User> getQueryWrapper(UserQueryRequest userQueryRequest) {
        ThrowUtils.throwIf(userQueryRequest == null, ErrorCode.PARAMS_ERROR);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        Long id = userQueryRequest.getId();
        String userName = userQueryRequest.getUserName();
        String userProfile = userQueryRequest.getUserProfile();
        String sortField = userQueryRequest.getSortField();
        String sortOrder = userQueryRequest.getSortOrder();
        queryWrapper.eq(id != null, "id", id);
        queryWrapper.like(StrUtil.isNotBlank(userName), "userName", userName);
        queryWrapper.like(StrUtil.isNotBlank(userProfile), "userProfile", userProfile);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
        return queryWrapper;
    }

    /**
     * 获取当前登录用户
     *
     * @param request
     * @return
     */
    @Override
    public User getLoginUser(HttpServletRequest request) {
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        User currentUser = (User) userObj;
        ThrowUtils.throwIf(currentUser == null || currentUser.getId() == null, ErrorCode.NOT_LOGIN_ERROR);
        // 查询数据库
        Long id = currentUser.getId();
        currentUser = this.getById(id);
        ThrowUtils.throwIf(currentUser == null, ErrorCode.NOT_FOUND_ERROR);
        return currentUser;
    }

    /**
     * 获取当前登录用户
     *
     * @param request
     * @return
     */
    @Override
    public UserVO getLoginUserVO(HttpServletRequest request) {
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        User currentUser = (User) userObj;
        ThrowUtils.throwIf(currentUser == null || currentUser.getId() == null, ErrorCode.NOT_LOGIN_ERROR);
        // 查询数据库
        Long id = currentUser.getId();
        currentUser = this.getById(id);
        UserVO userVO = new UserVO().objToVO(currentUser);
        ThrowUtils.throwIf(userVO == null, ErrorCode.NOT_FOUND_ERROR);
        return userVO;
    }

    /**
     * 密码加盐操作
     */
    public String passwordSalt(String password) {
        String salt = "jige";
        String passwordSalt = salt + password;
        return DigestUtils.md5DigestAsHex(passwordSalt.getBytes());
    }
}




